package com.apes.fn.business.insurance.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.crm.business.model.InsuranceCompanyDetail;
import com.apes.fn.business.insurance.modle.InsuranceOrder;
import com.apes.fn.business.insurance.modle.InsuranceOrderItem;
import com.apes.fn.business.insurance.repository.InsuranceOrderRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.pi.model.Timestamp;
import com.apes.pi.repository.TimestampRepository;
import com.apes.pi.service.PiManager;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName : InsuranceOrderService
 * @Description : 业务层
 * @Author : WSJ
 * @Date: 2020-05-20 17:25
 */
@Service("insuranceOrderService")
public class InsuranceOrderService extends DomainService {
    @Autowired
    private InsuranceOrderRepository orderRepository;
    @Autowired
    private PiManager piManager;
    @Autowired
    private TimestampRepository timestampRepository;
    @Autowired
    private  PolicyInformationService informationService;

    @Autowired
    private PartyRoleRepository roleRepository;


    public void saveInsuranceOrder () throws ParseException {
        String dateTime;
        String APIName = "fn.insurance.queryInsuranceOrder";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd.HHmmss.SSS");
        //首先获取到最新调用接口时间
        Timestamp timestamp = timestampRepository.findOne(APIName);
        JSONObject response = informationService.getAPPData(timestamp,"2");
        if (response.getBoolean("success")) {
            JSONArray data = response.getJSONArray("data");
            if (data.size() >0) {
                data.forEach(
                        item -> {
                            JSONObject parameters = JSONObject.parseObject(item.toString());
                            try {
                                if (parameters.getDouble("commerceTotalDiscounted")==0.0||parameters.getDouble("itemForcePrice")==0.0)return;
                                insertInsuranceOrder(parameters);
                            } catch (RuntimeException | ParseException e) {
                                throw new RuntimeException(e);
                            }
                        }
                );
                //如果拉取到数据,则需要以app排序后得最后一条数据得时间戳为准
                Date date = informationService.changeTime(data.getJSONObject(data.size() - 1).getJSONObject("order").getLongValue("updatedAt"));
                Instant instant = date.toInstant();
                LocalDateTime localDateTime = instant.atZone(ZoneOffset.of("+8")).toLocalDateTime();
                dateTime = localDateTime.format(formatter);
            }else {
                //获取北京时间的时间戳
                dateTime = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
            }
            informationService.insertTimestamp(timestamp,APIName,dateTime);
        }
    }
    public InsuranceOrder appCreateInsuranceOrder(SimpleRequest simpleRequest){
        JSONObject jo = simpleRequest.getJO();
        InsuranceOrder order = null;
        try {
            order = insertInsuranceOrder(jo);
        } catch (RuntimeException | ParseException e) {
            throw new RuntimeException(e);
        }
        return order;
    }

    /**
     * 生成保险订单
     * @param
     * @param parameters
     */
    private InsuranceOrder insertInsuranceOrder(JSONObject parameters) throws ParseException {
        InsuranceOrder insurance = packageInsuranceOrder(parameters);
        if (insurance.getInsuranceOrderItems().size() == 0) {
            JSONArray formList = parameters.getJSONArray("formList");
            if (formList==null) formList=new JSONArray() ;
            formList.forEach(
                    item -> {
                        JSONObject object =(JSONObject) item;
                        InsuranceOrderItem orderItem = packageInsuranceOrderItem(object);
                        orderItem.setInsuranceOrder(insurance);
                        insurance.getInsuranceOrderItems().add(orderItem);
                    }
            );
        }
        if (Objects.equals("生成保单",insurance.getStateName())){
            insurance.setInsuranceManagementFee(
                    getInsuranceManagementFee(insurance.getCompany().getId()) * (insurance.getCommercialInsurance() + insurance.getCompulsoryInsurance())
            );
        }
        return orderRepository.saveAndFlush(insurance);


    }
    /**
     * 包装保险订单
     * @param
     * @param param
     */
    private InsuranceOrder packageInsuranceOrder(JSONObject param) throws ParseException {
        InsuranceOrder insurance =
                orderRepository.findAll(JpaDsl.toCriteriaByEq("APPOrder", param.getString("id"))).stream().findFirst().orElse(null);
        if (insurance == null ) {
            insurance = new InsuranceOrder();
        }
        insurance.setAPPOrder(param.getString("id"));
        insurance.setLicensePlate(param.getString("carLicense"));
        insurance.setExternalStaff(param.getString("external_personnel"));
        //退保信息
        insurance.setCommercialAbolishAmount(param.getDoubleValue("commercialAbolishAmount"));
        insurance.setCompulsoryAbolishAmount(param.getDoubleValue("compulsoryAbolishAmount"));
        insurance.setDrivingAbolishAmount(param.getDoubleValue("drivingAbolishAmount"));
        insurance.setRedPacketAmount(param.getDoubleValue("redPacketAmount"));
        insurance.setRebateAmount(param.getDoubleValue("rebateAmount"));
        insurance.setBelongPlan(param.getString("belongPlan"));
        //保险信息
        insurance.setCarShipTax(param.getDouble("taxMoney"));
        insurance.setCommercialInsurance(param.getDouble("commerceTotalDiscounted"));
        insurance.setCompulsoryInsurance(param.getDouble("itemForcePrice"));

        insurance.setCompulsoryInsuranceStart(param.getDate("forceStartDate"));
        insurance.setCompulsoryInsuranceEnd(param.getDate("forceEndDate"));
        insurance.setOrigin(param.getString("origin"));
        insurance.setCommercialInsuranceStart(param.getDate("commerceStartDate"));
        insurance.setCommercialInsuranceEnd(param.getDate("commerceEndDate"));
        insurance.setDrivingInsuranceName(param.getString("drivingInsuranceName"));
        insurance.setDrivingInsuranceAmount(param.getDoubleValue("drivingInsuranceAmount"));
        JSONObject commission = param.getJSONObject("commissionMsg");
        if (commission!=null){
            insurance.setDiscountType(commission.getString("policyReturnType"));
            insurance.setDiscountPlan(commission.getString("policyType"));
        }
        insurance.setDiscountTypeName(param.getString("policyReturnTypeLabel"));
        insurance.setDiscountPlanName(param.getString("policyTypeLabel"));
        insurance.setEMaintain(param.getString("emaintainType"));

        JSONObject order = param.getJSONObject("order");
        if (order!=null||!"系统导入".equals(param.getString("origin"))){
            insurance.setReceiptDate(informationService.changeTime(order.getLongValue("finishPaymentAt")));
            if (!StringUtils.isEmpty(order.getString("refundAt"))){
                insurance.setRefundDate(informationService.changeTime(order.getLongValue("refundAt")));
            }
            if (!StringUtils.isEmpty(order.getString("cancellationAt"))){
                insurance.setVoidDate(informationService.changeTime(order.getLongValue("cancellationAt")));
            }
            if (!StringUtils.isEmpty(order.getString("dischargeInsuranceAt"))) {
                insurance.setAbolishDate(informationService.changeTime(order.getLongValue("dischargeInsuranceAt")));
            }
            insurance.setState(order.getString("status"));
            insurance.setStateName(order.getString("statusLabel"));
        }
        JSONObject insuranceRefund = param.getJSONObject("insuranceRefund");
        if (insuranceRefund!=null&&!StringUtils.isEmpty(insuranceRefund.getString("refundActualInsuranceTotalPrice"))) {
            insurance.setAbolishAmount(insuranceRefund.getDoubleValue("refundActualInsuranceTotalPrice"));
        }

        packageEntity(param,insurance);
        return  insurance;
    }

    /**
     * 包装保险订单明细
     * @param
     * @param param
     */
    private InsuranceOrderItem packageInsuranceOrderItem(JSONObject param) {
        InsuranceOrderItem orderItem = new InsuranceOrderItem();
        orderItem.setName(param.getString("title"));
        orderItem.setInsurancePrice(param.getDouble("price"));
        return  orderItem;
    }

    /**
     * 包装保单信息的实体
     * @param param
     * @param
     */
    private void packageEntity(JSONObject param, InsuranceOrder order) {
        //获取门店, 供应商 , 业务员
        if (!(param.getString("storeCode")==null&&param.getString("origin").equals("系统导入"))){
            Dept dept = SpringManager.getBean(DeptRepository.class).findOne(param.getString("storeCode"));
            if (dept == null){
                throw new RuntimeException("该门店编码在系统中无对应信息,编码: " + param.getString("storeCode"));
            }
            order.setDept(dept);
            order.setCompany(dept.getCompany());
        }
        String staffCode = param.getString("staffCode");
        if (param.getString("staffCode")==null&&param.getString("origin").equals("系统导入"))staffCode="00002256";
        PartyRole staff = roleRepository.findOne(staffCode);
        if (staff == null){
            throw new RuntimeException("该员工在系统中无对应信息,编码: " + staffCode);
        }
        order.setSalesman(staff);
        if (param.getString("supplyCompanyCode")==null&&param.getString("origin").equals("系统导入"))param.put("supplyCompanyCode","00002256");
        if (StringUtils.isEmpty(param.getString("supplyCompanyCode"))){
            InsuranceCompanyDetail insuranceCompany = informationService.getInsuranceCompany(param);
            order.setSupplier(insuranceCompany.getSupplier());
        }else {
            PartyRole supplier = roleRepository.findOne(param.getString("supplyCompanyCode"));
            if (Objects.isNull(supplier)) {
                throw new RuntimeException("系统中无对应数据,编码:"+param.getString("supplyCompanyCode"));
            }
            order.setSupplier(supplier);
        }
    }

    /**
     * 获取车险销售管理费
     *
     * @param merchantId
     * @return
     */
    public double getInsuranceManagementFee(String merchantId) {
        PartyRole company = SpringManager.getBean(PartyRoleRepository.class).findOne(merchantId);
        Map map = MapUtil.mapper(
                "OPERATION", company.getParty().getCorporate().getOperation().getId(), "COMPANY_ID", merchantId, "SYS_RQ", new Date(), "conditionStrategyId", "GL_CX_SK"
        );
        Object obj = this.invoke("condition.execConditionStrategy", map);
        JSONObject result = new JSONObject(MapUtil.mapped(obj));
        return result.getDoubleValue("T001");
    }

    public String synchronizeOrders (SimpleRequest request){
        JSONObject param = request.getJO();
        String appOrder = param.getString("appOrder");
        InsuranceOrder insuranceOrder = orderRepository.findAll(JpaDsl.toCriteriaByEq("APPOrder", appOrder)).stream().findFirst().orElse(null);
        if (Objects.isNull(insuranceOrder)) {
            insuranceOrder = new InsuranceOrder();
        }
        insuranceOrder.setAPPOrder(appOrder);
        insuranceOrder.setState(param.getString("state"));
        insuranceOrder.setStateName(param.getString("stateName"));
        insuranceOrder.setReceiptDate(param.getDate("receiptDate"));
        insuranceOrder.setDrivingInsuranceName(param.getString("drivingInsuranceName"));
        insuranceOrder.setDrivingInsuranceAmount(param.getDoubleValue("drivingInsuranceAmount"));
        insuranceOrder.setLicensePlate(param.getString("licensePlate"));
        //退保信息
        insuranceOrder.setDrivingAbolishAmount(param.getDoubleValue("drivingAbolishAmount"));
        if (!StringUtils.isEmpty(param.getString("refundDate"))) {
            insuranceOrder.setRefundDate(param.getDate("refundDate"));
        }
        if (!StringUtils.isEmpty(param.getString("abolishDate"))) {
            insuranceOrder.setAbolishAmount(param.getDoubleValue("abolishAmount"));
            insuranceOrder.setAbolishDate(param.getDate("abolishDate"));
        }
        packageEntity(param, insuranceOrder);
        if (Objects.equals("生成保单",insuranceOrder.getStateName())){
            insuranceOrder.setInsuranceManagementFee(
                    getInsuranceManagementFee(insuranceOrder.getCompany().getId()) * (insuranceOrder.getDrivingInsuranceAmount())
            );
        }
        insuranceOrder = orderRepository.saveAndFlush(insuranceOrder);
        if (param.containsKey("policyInformation") && param.getJSONArray("policyInformation").size() > 0 ) {
            informationService.appSynchronizePolicy(param,insuranceOrder);
        }
        return insuranceOrder.getAPPOrder();
    }

    /**
     * app同步创建保险订单的入参格式化
     * @param request
     * @return
     */
    public Object appCreateInsuranceOrderFormat(SimpleRequest request){
        JSONObject jo = request.getJO();
        String id = jo.getString("id");
        jo.put("lockId","insuranceOrder_appOrder_" + id);
        return jo;
    }
}
